<?php
// +----------------------------------------------------------------------
// | Bwsaas
// +----------------------------------------------------------------------
// | Copyright (c) 2015~2020 http://www.buwangyun.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Gitee ( https://gitee.com/buwangyun/bwsaas )
// +----------------------------------------------------------------------
// | Author: buwangyun <hnlg666@163.com>
// +----------------------------------------------------------------------
// | Date: 2020-9-28 10:55:00
// +----------------------------------------------------------------------

namespace buwang\util;

use buwang\exception\WxException;

/**
 * 引用微信签名认证类
 */
class Sign
{
    /**
     * createSignature 生成签名串
     * @param $data
     * @param string $signType
     * @return string
     */
    public static function createSignature(array $data, $key, $signType = 'HMAC-SHA256')
    {
        //签名步骤一：按字典序排序参数
        ksort($data);
        $string = self::formatUrlParams($data);
        //签名步骤二：在string后加入KEY
        $string = $string . "&key=" . $key;
        //签名步骤三：MD5加密或者HMAC-SHA256
        if ($signType == 'md5') {
            //如果签名小于等于32个,则使用md5验证
            $string = md5($string);
        } else {
            //是用sha256校验
            $string = hash_hmac("sha256", $string, $key);
        }
        //签名步骤四：所有字符转为大写
        $result = strtoupper($string);
        return $result;
    }

    /**
     * formatUrlParams 格式化成url参数
     * @param $data
     * @return string
     */
    public static function formatUrlParams(array $data)
    {
        $buff = "";
        foreach ($data as $k => $v) {
            if ($k != "sign" && $v !== "" && $v !== "null" && !is_array($v)) {
                $buff .= $k . "=" . $v . "&";
            }
        }
        $buff = trim($buff, "&");
        return $buff;
    }

    /**
     * 输出xml字符
     * @throws WxException
     **/
    public static function toXml($data)
    {
        if (!is_array($data) || count($data) <= 0) {
            throw new WxException(200,"xml字符输入错误");
        }
        $xml = "<xml>";
        foreach ($data as $key => $val) {
            if (is_numeric($val)) {
                $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
            } else {
                $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
            }
        }
        $xml .= "</xml>";
        return $xml;
    }

    /**
     * 将xml转为array
     * @param string $xml
     * @throws WxException
     */
    public static function fromXml($xml)
    {
        if (!$xml) {
            throw new WxException(200,"xml不能为空，解析错误");
        }
        //将XML转为array
        //禁止引用外部xml实体
        if(\PHP_VERSION_ID < 80000) libxml_disable_entity_loader(true);
        $xml_parser = xml_parser_create();
        if (!xml_parse($xml_parser, $xml, true)) {
            xml_parser_free($xml_parser);
            throw new WxException(200,"xml解析错误");
        } else {
            $arr = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        }
        return $arr;
    }

}
